﻿// FluentViewModel (http://fluentviewmodel.codeplex.com/)
//
// Copyright © 2010 Kialco Group 
//
// The contents of this file are subject to the Mozilla Public
// License Version 1.1 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of
// the License at http://www.mozilla.org/MPL/
// 
// Software distributed under the License is distributed on an 
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
// implied. See the License for the specific language governing
// rights and limitations under the License.

using System;
using System.Collections.Generic;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace FluentViewModel
{
    public sealed class ServiceLocator : IServiceLocator
    {
        private readonly IWindsorContainer windsorContainer;
        private readonly IViewModelContainer viewModelContainer;
        private readonly IDictionary<string, Func<object>> services;

        public ServiceLocator()
        {
            windsorContainer = new WindsorContainer();
            viewModelContainer = new ViewModelContainer();
            services = new Dictionary<string, Func<object>>();
            Current = this;
        }

        internal static IServiceLocator Current { get; private set; }

        public void RegisterService(IServiceConfiguration configuration)
        {
            var componentRegistration = Component
                .For(configuration.ServiceType)
                .ImplementedBy(configuration.ServiceImplementationType);
            componentRegistration = configuration.Transient
                                        ? componentRegistration.LifeStyle.Transient
                                        : componentRegistration.LifeStyle.Singleton;
            windsorContainer.Register(componentRegistration);
            services[configuration.ServiceType.FullName] = () => windsorContainer.Resolve(configuration.ServiceType);
        }

        public void RegisterViewModel(IViewModelConfiguration configuration)
        {
            viewModelContainer.Register(configuration);
            services[configuration.ViewModelType.FullName] = () => viewModelContainer.Resolve(configuration.ViewModelType);
        }

        public object Resolve(Type type)
        {
            return services[type.FullName]();
        }

        public TService Resolve<TService>()
        {
            return (TService)Resolve(typeof(TService));
        }
    }
}